package com.common.baselibrary.utils;

import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.media.ExifInterface;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import com.common.baselibrary.log.LogUtil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;


public class BitmapUtil {

    private static final String TAG = "BitmapUtil";

    public final static int DEFAULT_OUT_WIDTH = 400;
    public final static int DEFAULT_OUT_HEIGHT = 400;
    public final static int IMG_COMPRESS_OK = 1;
    public final static int IMG_COMPRESS_ERR = 2;
    public final static int DEFAULT_OUT_SIZE = 204800;
    private final static String FILE_SUF_TEMP = ".temp_dat";
    private final static String FILE_MERGE_TEMP = ".mer_temp_dat";

    Dialog progressDialog;
    Handler uiHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case IMG_COMPRESS_OK:
                    if (null != progressDialog && progressDialog.isShowing()) {
                        progressDialog.cancel();
                    }
                    break;
                case IMG_COMPRESS_ERR:
                    if (null != progressDialog && progressDialog.isShowing()) {
                        progressDialog.cancel();
                    }
                    break;
            }
        }
    };

    /**
     * 获取图片宽度、高度
     * 注意：获取的宽、高在不同分辨率下的值不一致
     *
     * @param context
     * @param bitmapResId
     * @return
     */
    public static int[] getBitmapWidthAndHeight(Context context, int bitmapResId) {
        if (bitmapResId <= 0) {
            return null;
        }
        int[] sizeArray = new int[2];
        try {
            BitmapFactory.Options newOpts = new BitmapFactory.Options();
            newOpts.inJustDecodeBounds = true;//if true, don't decode bitmap, only get info
            BitmapFactory.decodeResource(context.getResources(), bitmapResId, newOpts);
            sizeArray[0] = newOpts.outWidth;
            sizeArray[1] = newOpts.outHeight;
        } catch (Exception e) {
            LogUtil.w(TAG, "catch Exception throw by getBitmapWidthAndHeight.", e);
        }
        return sizeArray;
    }

    /**
     * 图片压缩
     *
     * @param srcPath 图片路径
     */
    public static Bitmap getimage(String srcPath, int outWidth, int outHeight) {
        if (StringUtils.isEmpty(srcPath)) {
            LogUtil.e("getimage", "路径不能为空！");
            return null;
        }
        if (outWidth <= 0) {
            outWidth = DEFAULT_OUT_WIDTH;
        }
        if (outHeight <= 0) {
            outHeight = DEFAULT_OUT_HEIGHT;
        }
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        newOpts.inInputShareable = true;
        newOpts.inPurgeable = true;// 设置图片可以被回收
        newOpts.inPreferredConfig = Config.RGB_565;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空

        newOpts.inJustDecodeBounds = false;
        // 缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        int tempbe1 = 1;
        int tempbe2 = 1;
        tempbe1 = (int) (newOpts.outWidth / outWidth);
        tempbe2 = (int) (newOpts.outHeight / outHeight);
        if (tempbe1 < tempbe2) {
            be = tempbe2;
        } else {
            be = tempbe1;
        }
        if (be <= 0)
            be = 1;
        LogUtil.d("压缩比例：" + be + "tempbe1:" + tempbe1 + "tempbe2:" + tempbe2);
        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        try {
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        } catch (OutOfMemoryError e) {
            LogUtil.e("compressImage OutOfMemoryError");
            e.printStackTrace();
            if (null != bitmap) {
                return bitmap;
            }
        }
        if (null == bitmap) {
            return null;
        }
//		bitmap = compressImage(bitmap, 200);
        return isRotaing(srcPath, bitmap);
    }

    public static Bitmap compressImageDeep(Bitmap image, int q) {
        if (null == image) {
            LogUtil.e("compressImageDeep", "image = null");
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        LogUtil.i("压缩前大小：" + baos.toByteArray().length / 1024);
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            image = compressImage(image, q);
            baos.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        }
        LogUtil.i("压缩后大小：" + baos.toByteArray().length / 1024);
        return image;
    }

    public static Bitmap compressImage(Bitmap image, int q) {
        if (null == image) {
            LogUtil.e("compressImage", "image = null");
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int compress = 100;
        LogUtil.d("压缩前:" + baos.toByteArray().length / 1024);
        while (baos.toByteArray().length / 1024 > q && compress >= 10) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            if (compress == 10) {
                compress -= 9;
            } else {
                compress -= 10;// 每次都减少10
            }
            LogUtil.d("压缩", "compress :" + compress + " length:" + baos.toByteArray().length / 1024);
            image.compress(Bitmap.CompressFormat.JPEG, compress, baos);// 这里压缩options%，把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inInputShareable = true;
        options.inPurgeable = true;// 设置图片可以被回收
        options.inPreferredConfig = Config.RGB_565;
        try {
            image = BitmapFactory.decodeStream(isBm, null, options);// 把ByteArrayInputStream数据生成图片
        } catch (OutOfMemoryError e) {
            // TODO: handle exception
            LogUtil.e("compressImage OutOfMemoryError");
        } finally {
            if (null != isBm) {
                try {
                    isBm.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                isBm = null;
            }
        }
        baos.reset();// 重置baos即清空baos
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        LogUtil.d("压缩后:" + baos.toByteArray().length / 1024);
        if (baos != null) {
            try {
                baos.flush();
                baos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return image;
    }

    public Bitmap revitionImageSize(Context context, String path, int size)
            throws IOException {
        // 取得图片
        InputStream temp = context.getAssets().open(path);
        BitmapFactory.Options options = new BitmapFactory.Options();
        // 这个参数代表，不为bitmap分配内存空间，只记录一些该图片的信息（例如图片大小），说白了就是为了内存优化
        options.inJustDecodeBounds = true;
        // 通过创建图片的方式，取得options的内容（这里就是利用了java的地址传递来赋值）
        BitmapFactory.decodeStream(temp, null, options);
        // 关闭流
        temp.close();

        // 生成压缩的图片
        int i = 0;
        Bitmap bitmap = null;
        while (true) {
            // 这一步是根据要设置的大小，使宽和高都能满足
            if ((options.outWidth >> i <= size)
                    && (options.outHeight >> i <= size)) {
                // 重新取得流，注意：这里一定要再次加载，不能二次使用之前的流！
                temp = context.getAssets().open(path);
                // 这个参数表示 新生成的图片为原始图片的几分之一。
                options.inSampleSize = (int) Math.pow(2.0D, i);
                // 这里之前设置为了true，所以要改为false，否则就创建不出图片
                options.inJustDecodeBounds = false;

                bitmap = BitmapFactory.decodeStream(temp, null, options);
                break;
            }
            i += 1;
        }
        return bitmap;
    }

    /**
     * @param bmp         位图
     * @param outFilePath 输出文件路径
     * @param quality     压缩率 (80表示压缩掉20%; 如果不压缩是100，表示压缩率为0)
     * @return
     */
    public static boolean saveBitmap2file(Bitmap bmp, String outFilePath,
                                          int quality) {
        CompressFormat format = Bitmap.CompressFormat.JPEG;
        OutputStream stream = null;
        boolean flag = false;
        try {
            stream = new FileOutputStream(outFilePath);
            flag = bmp.compress(format, quality, stream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (null != stream) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                stream = null;
            }
        }
        return flag;
    }



    /**
     * 旋转图片
     *
     * @param image
     * @param angle2 旋转角度
     * @return
     */
    public static Bitmap rotaingImageView(Bitmap image, int angle2) {
        if (null == image) {
            LogUtil.e("rotaingImageView", "image = null");
            return null;
        }
        // 旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle2);
        // 创建新的图片
        try {
            image = Bitmap.createBitmap(image, 0, 0, image.getWidth(),
                    image.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
            LogUtil.e("rotaingImageView OutOfMemoryError");
        }

        return image;
    }

    /**
     * 识别图片方向并自动旋转角度
     *
     * @param imgpath
     * @param bm
     * @return
     */
    public static Bitmap isRotaing(String imgpath, Bitmap bm) {
        if (null == bm) {
            LogUtil.e("isRotaing", "bm = null");
            return null;
        }
        int digree = 0;
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(imgpath);
        } catch (IOException e) {
            e.printStackTrace();
            exif = null;
        }
        if (exif != null) {
            // 读取图片中相机方向信息
            int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_UNDEFINED);
            // 计算旋转角度
            switch (ori) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    digree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    digree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    digree = 270;
                    break;
                default:
                    digree = 0;
                    break;
            }
        }
        if (digree != 0) {
            try {
                // 旋转图片
                Matrix m = new Matrix();
                m.postRotate(digree);
                bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
                        bm.getHeight(), m, true);
                LogUtil.d("isRotaing", "旋转图片" + digree + "度");
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
                LogUtil.e("isRotaing", "哎呦，就旋转个图片就溢出了。。。。");
                if (null != bm) {
                    return bm;
                }
            }
        }
        return bm;
    }

    public static byte[] imageZoom(Bitmap bitMap) {
        if (null == bitMap) {
            LogUtil.e("imageZoom", "bitMap = null");
            return null;
        }
        byte[] b = null;
        ByteArrayOutputStream baos = null;
        try {
            // 图片允许最大空间 单位：KB
            double maxSize = 100.00;
            // 将bitmap放至数组中，意在bitmap的大小（与实际读取的原文件要大）
            baos = new ByteArrayOutputStream();
            bitMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            b = baos.toByteArray();
            // 将字节换成KB
            double mid = b.length / 1024;
            // 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
            if (mid > maxSize) {
                // 获取bitmap大小 是允许最大大小的多少倍
                double i = mid / maxSize;
                // 开始压缩 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
                // （1.保持刻度和高度和原bitmap比率一致，压缩后也达到了最大大小占用空间的大小）
                if (Math.sqrt(i) != 0) {
                    bitMap = zoomImage(bitMap, bitMap.getWidth() / Math.sqrt(i),
                            bitMap.getHeight() / Math.sqrt(i));
                }
                // 将bitmap放至数组中，意在bitmap的大小（与实际读取的原文件要大）
                baos = null;
                baos = new ByteArrayOutputStream();
                bitMap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                b = baos.toByteArray();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (null != baos) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                baos = null;
            }
        }
        return b;
    }

    /***
     * 图片的缩放方法
     *
     * @param bgimage   ：源图片资源
     * @param newWidth  ：缩放后宽度
     * @param newHeight ：缩放后高度
     * @return
     */
    public static Bitmap zoomImage(Bitmap bgimage, double newWidth,
                                   double newHeight) {
        if (null == bgimage) {
            LogUtil.e("zoomImage", "bgimage = null");
            return null;
        }
        // 获取这个图片的宽和高
        float width = bgimage.getWidth();
        float height = bgimage.getHeight();
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = null;
        try {
            bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
                    (int) height, matrix, true);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
            LogUtil.e("zoomImage", "啊啊啊啊啊啊啊啊啊啊啊啊啊，内存溢出了。。。");
            if (null != bitmap) {
                return bitmap;
            }
        }
        return bitmap;
    }


    public static Bitmap readBitMap(Context context, int resId) {
        InputStream is = null;
        Bitmap bitmap = null;
        try {
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inPreferredConfig = Bitmap.Config.RGB_565;
            opt.inPurgeable = true;
            opt.inInputShareable = true;
            //获取资源图片
            is = context.getResources().openRawResource(resId);
            bitmap = BitmapFactory.decodeStream(is, null, opt);
        } catch (NotFoundException e) {
            e.printStackTrace();
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                is = null;
            }
        }
        return bitmap;
    }

    /**
     * @param urlpath
     * @return Bitmap
     * 根据图片url获取图片对象
     */
    public static Bitmap getBitMBitmap(String urlpath) {
        Bitmap map = null;
        InputStream in = null;
        if (StringUtils.isNotEmpty(urlpath)) {
            try {
                URL url = new URL(urlpath);
                URLConnection conn = url.openConnection();
                conn.connect();
                in = conn.getInputStream();
                map = BitmapFactory.decodeStream(in);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (null != in) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    in = null;
                }
            }
        }
        return map;
    }

    /**
     * 获取圆角位图的方法
     *
     * @param bitmap 需要转化成圆角的位图
     * @param pixels 圆角的度数，数值越大，圆角越大
     * @return 处理后的圆角位图
     */
    public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    public static byte[] bitmapToByte(Bitmap b) {
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        b.compress(CompressFormat.JPEG, 100, bao);
        return bao.toByteArray();
    }

    public static Bitmap bytesToBitmap(byte[] bytes) {
        if (null != bytes) {
            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            return bitmap;
        } else {
            return null;
        }
    }

    /**
     * 获取可用的存储路径 后面带了分隔符了 构建一个sdk卡缓存目录 如果sd卡不可用 则返回应用内部cache目录
     *
     * @return
     */
    public static String getAppCachePath(Context context) {
        if (hasSDCard()) {
            return Environment.getExternalStorageDirectory().getPath() + File.separator
                    + "AppCache" + File.separator;
        } else {
            return context.getCacheDir() + File.separator;
        }
    }


    public static boolean hasSDCard() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            return true;
        } else {
            return false;
        }
    }

    public static Bitmap getScaleBitmap(int imgWidth, Bitmap rawBitmap) {
        float ratio = 0;
        boolean isEnd = false;
        Bitmap scaleBitmap = null;
        Bitmap bitmapTemp = rawBitmap;
        while (!isEnd) {
            float w = rawBitmap.getWidth();
            float h = rawBitmap.getHeight();
            ratio = getRatio(w, h, imgWidth);
            if (ratio > 0.5) {
                isEnd = true;
            } else {
                ratio = 0.5f;
            }
            Matrix matrix = new Matrix();
            if (w > h) {
                matrix.postScale(ratio, ratio * w / h);
            } else {
                matrix.postScale(ratio * h / w, ratio);
            }
            if (!isEnd) {
                rawBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, (int) w, (int) h, matrix, true);
                bitmapTemp.recycle();
                bitmapTemp = rawBitmap;
            } else {
                scaleBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, (int) w, (int) h, matrix, true);
//				rawBitmap.recycle();
                rawBitmap = null;
                bitmapTemp = null;
            }
        }
        return scaleBitmap;
    }

    private static float getRatio(float w, float h, int imageW) {
        float ratio = 0;
        if (w > h) {
            ratio = imageW / w;
        } else {
            ratio = imageW / h;
        }
        return ratio;
    }

    /**
     * 将两张位图拼接成一张(横向拼接)
     *
     * @param first
     * @param second
     * @return
     */
    public static Bitmap add2Bitmap(Bitmap first, Bitmap second) {
        int width = first.getWidth() + second.getWidth();
        int height = Math.max(first.getHeight(), second.getHeight());
        Bitmap result = Bitmap.createBitmap(width, height, Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(first, 0, 0, null);
        canvas.drawBitmap(second, first.getWidth(), 0, null);
        return result;
    }


    /**
     * 将两张位图拼接成一张(shu向拼接)
     *
     * @param first
     * @param second
     * @return
     */
    public static Bitmap add2BitmapforRow(Bitmap first, Bitmap second) {
        int width = Math.max(first.getWidth(), second.getWidth());
        int height = first.getHeight() + second.getHeight();
        Bitmap result = Bitmap.createBitmap(width, height, Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(first, 0, 0, null);
        canvas.drawBitmap(second, 0, first.getHeight(), null);
        return result;
    }


    /**
     * 保存图片 从from路径到to路径 包括图片宽度
     *
     * @param from     图片 原先路径
     * @param to       图片 压缩过后路径
     * @param size     图片数量
     * @param imgWidth 单个图片宽度
     * @return
     */
    public static boolean saveBitmap(String from, String to, int size, int imgWidth) {
        InputStream inputStream = null;
        OutputStream os = null;
        try {
            File mRootDir = new File(from);
            if (!mRootDir.exists() || !mRootDir.isDirectory()) {
                return false;
            }
            // 先清理临时文件夹的数据，避免干扰
            File mRootTemp = new File(to);
            if (mRootTemp.exists() && mRootTemp.isDirectory()) {
                File[] files = mRootTemp.listFiles();
                if (files != null && files.length > 0) {
                    for (File file : files) {
                        if (file.isFile()) {
                            file.delete();
                        }
                    }
                }
            } else {
                mRootTemp.mkdirs();
            }
            // 本地处理图片
            BitmapFactory.Options opts = new BitmapFactory.Options();
            opts.inDither = false;
            opts.inPreferredConfig = Bitmap.Config.RGB_565;
            opts.inScaled = false;

            boolean flag = false;
            int index = 0;

            for (index = 0; index < size; index++) {
                flag = false;
                // 读取原图
                File file = new File(mRootDir, index + ".dat");
                Bitmap bitmap1 = null;
                Bitmap bitmap2 = null;
                if (file.exists()) {
                    inputStream = new FileInputStream(file);
                    bitmap1 = BitmapFactory.decodeStream(inputStream, null, opts);
                    inputStream.close();
                    file = null;
                }
                // 缩放图片
                if (bitmap1 != null) {
                    bitmap2 = BitmapUtil.getScaleBitmap(imgWidth, bitmap1);
                    bitmap1 = null;
                }
                // 输出JPG图片
                if (bitmap2 != null) {
                    file = new File(mRootTemp, index + FILE_SUF_TEMP);
                    os = new FileOutputStream(file);
                    bitmap2.compress(Bitmap.CompressFormat.JPEG, 100, os);
                    os.close();
                    bitmap2.recycle();
                    bitmap2 = null;
                    file = null;
                    flag = true;
                }
                if (flag == false) {
                    return false;
                }
            }

            if (index >= size) {
                return true;
            }

        } catch (OutOfMemoryError error) {
            error.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }


    public static Bitmap addRecs(Bitmap map, int row, int line) {
        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        int width = map.getWidth();
        int height = map.getHeight();
        Bitmap result = Bitmap.createBitmap(width, height, Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(map, 0, 0, null);
        for (int lineX = 0; lineX < row + 1; lineX++) {
            canvas.drawLine(0, height / row * lineX, width, height / row * lineX, paint);
        }
        for (int lineY = 0; lineY < line + 1; lineY++) {
            canvas.drawLine(width / line * lineY, 0, width / line * lineY, height, paint);
        }
        return result;
    }




    /**
     * 图片压缩（尺寸压缩+质量压缩）
     *
     * @param imageFile       图片源文件
     * @param outImgMaxSize   输出图片文件大小上限
     * @param outImgMaxWidth  输出图片最大宽度
     * @param outImgMaxHeight 输出图片最大高度
     * @param callBack        回调
     */
    public void compressImage(Context context, final File imageFile, final int outImgMaxSize, final int outImgMaxWidth, final int outImgMaxHeight, final ICompressImageCallBack callBack) {
        if (null == imageFile || !imageFile.exists() || context == null || callBack == null) {
            return;
        }
        final String imagePath = imageFile.getPath();
        if (null != progressDialog) {
            progressDialog.setCancelable(false);
            progressDialog.setCanceledOnTouchOutside(false);
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    float oldsize = imageFile.length();// 压缩前大小
                    LogUtil.d(TAG, "原始文件大小：" + (oldsize / 1024) + " KB");

                    if (oldsize > outImgMaxSize) {//如果大于最大容量,需要压缩
                        final String newPath = imageFile.getParent() + "/" + System.currentTimeMillis() + ".jpg";
                        //尺寸压缩
                        Bitmap newBitmap = BitmapUtil.getimage(imagePath, outImgMaxWidth, outImgMaxHeight);
                        //质量压缩
                        compressAndGenImage(newBitmap, newPath, outImgMaxSize / 1024);
                        LogUtil.d(TAG, "压缩后大小：" + (new File(newPath).length() / 1024) + " KB");
                        uiHandler.sendMessage(uiHandler.obtainMessage(IMG_COMPRESS_OK));
                        uiHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callBack.onCompressSuccess(new File(newPath));
                            }
                        });
                    } else {
                        LogUtil.d(TAG, "小于" + (outImgMaxSize / 1024) + "KB无需压缩~~");
                        uiHandler.sendMessage(uiHandler.obtainMessage(IMG_COMPRESS_OK));
                        uiHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                callBack.onCompressSuccess(new File(imagePath));
                            }
                        });
                    }
                } catch (final Exception e) {
                    e.printStackTrace();
                    uiHandler.sendMessage(uiHandler.obtainMessage(IMG_COMPRESS_ERR));
                    uiHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callBack.onCompressFailed(e.getMessage());
                        }
                    });
                }
            }
        }).start();
    }

    /**
     * 质量压缩
     *
     * @param image
     * @param outPath
     * @param maxSize
     * @throws IOException
     */
    private void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // scale
        int options = 100;
        // Store the bitmap into output stream(no compress)
        image.compress(Bitmap.CompressFormat.JPEG, options, os);
        // Compress by loop
        while (os.toByteArray().length / 1024 > maxSize) {
            // Clean up os
            os.reset();
            // interval 10
            options -= 2;
            image.compress(Bitmap.CompressFormat.JPEG, options, os);
            LogUtil.d(TAG, "质量压缩-quality：" + options);
        }

        // Generate compressed image file
        FileOutputStream fos = new FileOutputStream(outPath);
        fos.write(os.toByteArray());
        fos.flush();
        fos.close();
        LogUtil.d(TAG, "已写出照片：" + outPath);
    }

    public interface ICompressImageCallBack {
        void onCompressSuccess(File imageFile);

        void onCompressFailed(String exception);
    }



    /**
     * 给图片加水印
     * @param context
     * @param src 图片
     * @param textWater 水印文字内容
     * @param x 水印x坐标
     * @param y 水印y坐标
     * @return
     */
    public static Bitmap addWaterMark(Context context, Bitmap src, String textWater, int x, int y) {
        Bitmap tarBitmap = src.copy(Bitmap.Config.ARGB_8888, true);
//        int w = tarBitmap.getWidth();
//        int h = tarBitmap.getHeight();
        Canvas canvas = new Canvas(tarBitmap);
        //启用抗锯齿和使用设备的文本字距
        Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
        //字体的相关设置
        textPaint.setTextSize(DimenUtil.sp2px(context, 10));//字体大小
        textPaint.setTypeface(Typeface.DEFAULT_BOLD);
        textPaint.setColor(Color.RED);
//        textPaint.setShadowLayer(3f, 1, 1, context.getResources().getColor(android.R.color.background_dark));
        //图片上添加水印的位置
        canvas.drawText(textWater, x, y, textPaint);
        canvas.save(Canvas.ALL_SAVE_FLAG);
        canvas.restore();
        return tarBitmap;
    }
}
